﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using SolutionExtender.AppCode;
using SolutionExtender.Interfaces;

namespace McTools.SolutionExtender.QueuePlugin
{
    public partial class QueueExportControl : UserControl, IExportControl
    {
        #region Variables

        /// <summary>
        /// Microsoft Dynamics CRM 2011 Organization service
        /// </summary>
        private readonly IOrganizationService _service;

        /// <summary>
        /// Indicates if this control found rules
        /// </summary>
        private bool _hasData;

        #endregion Variables

        #region Constructor

        /// <summary>
        /// Initializes a new instance of class QueueExportControl
        /// </summary>
        /// <param name="service">Microsoft Dynamics CRM 2011 Organization service</param>
        public QueueExportControl(IOrganizationService service)
        {
            _service = service;
            InitializeComponent();
        }

        #endregion Constructor

        #region Methods

        /// <summary>
        /// Loads list of queues
        /// </summary>
        private void QueueExportControlLoad(object sender, EventArgs e)
        {
            var items = new List<ListViewItem>();

            var qe = new QueryExpression("queue") {ColumnSet = new ColumnSet(true), Criteria = new FilterExpression()};
            qe.Criteria.AddCondition("name", ConditionOperator.DoesNotBeginWith, "<");
            qe.Criteria.AddCondition("name", ConditionOperator.DoesNotEndWith, ">");

            foreach (var queue in _service.RetrieveMultiple(qe).Entities)
            {
                var item = new ListViewItem(queue.Contains("name") ? queue["name"].ToString() : "(no name)");
                item.SubItems.Add(queue.Contains("emailaddress") ? queue["emailaddress"].ToString() : string.Empty);
                item.SubItems.Add(queue.Contains("description") ? queue["description"].ToString() : string.Empty);
                item.Tag = queue.Id;

                items.Add(item);
            }

            if (items.Count() == 0)
            {
                _hasData = false;
                lvItems.Visible = false;
                pnlNoItems.Visible = true;
            }
            else
            {
                _hasData = true;
                pnlNoItems.Visible = false;
                lvItems.Items.AddRange(items.ToArray());
            }
        }

        /// <summary>
        /// Gets a Xml list of selected queues
        /// </summary>
        /// <returns></returns>
        public XmlNodeList GetSelectedItems()
        {
            if(lvItems.SelectedItems.Count == 0 && _hasData)
            {
                pnlError.Visible = true;
                return null;
            }

            pnlError.Visible = false;

            var stringifiedXml = new StringBuilder();
            stringifiedXml.Append("<Root>");

            foreach (ListViewItem item in lvItems.SelectedItems)
            {
                // Retrieve duplicate detection rule
                var queue = _service.Retrieve("queue", (Guid)item.Tag, new ColumnSet(true));

                var queueObject = new Queue
                {
                    QueueId = chkExportWithId.Checked ? queue.Id : Guid.Empty,
                    AllowEmailCredentials =
                        queue.Contains("allowemailcredentials") &&
                        (bool)queue["allowemailcredentials"],
                    //BusinessUnitId = ((EntityReference)queue["businessunitid"]).Id,
                    Description =
                        queue.Contains("description")
                            ? queue["description"].ToString()
                            : string.Empty,
                    EmailAddress =
                        queue.Contains("emailaddress")
                            ? queue["emailaddress"].ToString()
                            : string.Empty,
                    EmailPassword =
                        queue.Contains("emailpassword")
                            ? queue["emailpassword"].ToString()
                            : string.Empty,
                    EmailUserName =
                        queue.Contains("emailusername")
                            ? queue["emailusername"].ToString()
                            : string.Empty,
                    IgnoreUnsolicitedEmail =
                        queue.Contains("ignoreunsolicitedemail") &&
                        (bool)queue["ignoreunsolicitedemail"],
                    IncomingEmailDeliveryMethod =
                        queue.Contains("incomingemaildeliverymethod")
                            ? ((OptionSetValue)queue["incomingemaildeliverymethod"]).Value
                            : (int?)null,
                    IncomingEmailFilteringMethod =
                        queue.Contains("incomingemailfilteringmethod")
                            ? ((OptionSetValue)queue["incomingemailfilteringmethod"]).Value
                            : (int?)null,
                    Name = queue.Contains("name") ? queue["name"].ToString() : string.Empty,
                    //OwnerId = ((EntityReference)queue["ownerid"]).Id,
                    //PrimaryUserId = ((EntityReference)queue["primaryuserid"]).Id,
                    OutgoingEmailDeliveryMethod =
                        queue.Contains("incomingemailfilteringmethod")
                            ? ((OptionSetValue)queue["incomingemailfilteringmethod"]).Value
                            : (int?)null,
                };

                stringifiedXml.Append(XmlSerializerHelper.Serialize(queueObject, true));
            }

            stringifiedXml.Append("</Root>");

            var doc = new XmlDocument();
            doc.LoadXml(stringifiedXml.ToString());

            return doc.DocumentElement.ChildNodes;
        }

        #endregion Methods

        #region Handlers

        private void LvItemsColumnClick(object sender, ColumnClickEventArgs e)
        {
            lvItems.Sorting = lvItems.Sorting == SortOrder.Ascending ? SortOrder.Descending : SortOrder.Ascending;

            lvItems.ListViewItemSorter = new ListViewItemComparer(e.Column, lvItems.Sorting);
        }

        #endregion Handlers
    }
}
